package com.yourcompany.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yourcompany.api.dto.RegionQueryDTO;
import com.yourcompany.api.entity.SysRegion;
import com.yourcompany.api.mapper.SysRegionMapper;
import com.yourcompany.api.service.SysRegionService;
import com.yourcompany.api.vo.RegionVO;
import com.yourcompany.common.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysRegionServiceImpl extends ServiceImpl<SysRegionMapper, SysRegion> implements SysRegionService {

    @Override
    public IPage<SysRegion> pageRegions(IPage<SysRegion> page, RegionQueryDTO queryDTO) {
        LambdaQueryWrapper<SysRegion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(queryDTO.getParentId() != null, SysRegion::getParentId, queryDTO.getParentId())
                .like(StringUtils.isNotBlank(queryDTO.getName()), SysRegion::getName, queryDTO.getName())
                .like(StringUtils.isNotBlank(queryDTO.getCode()), SysRegion::getCode, queryDTO.getCode())
                .eq(queryDTO.getLevel() != null, SysRegion::getLevel, queryDTO.getLevel())
                .eq(queryDTO.getStatus() != null, SysRegion::getStatus, queryDTO.getStatus())
                .orderByAsc(SysRegion::getSort);
        return page(page, wrapper);
    }

    @Override
    public List<RegionVO> getRegionTree(RegionQueryDTO queryDTO) {
        // 查询所有符合条件的地区
        LambdaQueryWrapper<SysRegion> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(queryDTO.getName()), SysRegion::getName, queryDTO.getName())
                .like(StringUtils.isNotBlank(queryDTO.getCode()), SysRegion::getCode, queryDTO.getCode())
                .eq(queryDTO.getLevel() != null, SysRegion::getLevel, queryDTO.getLevel())
                .eq(queryDTO.getStatus() != null, SysRegion::getStatus, queryDTO.getStatus())
                .orderByAsc(SysRegion::getSort);
        List<SysRegion> regions = list(wrapper);
        
        // 转换为VO
        List<RegionVO> regionVOs = regions.stream()
                .map(region -> BeanUtil.copyProperties(region, RegionVO.class))
                .collect(Collectors.toList());
        
        // 构建树形结构
        Map<Long, List<RegionVO>> parentMap = regionVOs.stream()
                .collect(Collectors.groupingBy(RegionVO::getParentId));
        
        regionVOs.forEach(region -> region.setChildren(parentMap.get(region.getId())));
        
        // 返回顶级节点
        return regionVOs.stream()
                .filter(region -> region.getParentId() == 0)
                .collect(Collectors.toList());
    }

    @Override
    public List<RegionVO> getChildren(Long parentId) {
        LambdaQueryWrapper<SysRegion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRegion::getParentId, parentId)
                .eq(SysRegion::getStatus, true)
                .orderByAsc(SysRegion::getSort);
        
        return list(wrapper).stream()
                .map(region -> BeanUtil.copyProperties(region, RegionVO.class))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addRegion(SysRegion region) {
        // 检查编码是否已存在
        if (lambdaQuery().eq(SysRegion::getCode, region.getCode()).exists()) {
            throw new BusinessException("地区编码已存在");
        }
        
        // 检查父级是否存在
        if (region.getParentId() != 0 && !lambdaQuery().eq(SysRegion::getId, region.getParentId()).exists()) {
            throw new BusinessException("父级地区不存在");
        }
        
        save(region);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRegion(SysRegion region) {
        // 检查编码是否已存在
        if (lambdaQuery()
                .eq(SysRegion::getCode, region.getCode())
                .ne(SysRegion::getId, region.getId())
                .exists()) {
            throw new BusinessException("地区编码已存在");
        }
        
        updateById(region);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRegion(Long id) {
        // 检查是否有子地区
        if (lambdaQuery().eq(SysRegion::getParentId, id).exists()) {
            throw new BusinessException("请先删除子地区");
        }
        
        removeById(id);
    }
} 